import zipfile
import shutil
import os
import logging
from pathlib import Path
from tool import is_sn_valid


# 配置日志
def setup_logging(log_file: str = "device_process.log"):
    """配置日志记录"""
    logging.basicConfig(
        level=logging.INFO,
        format="%(asctime)s - %(levelname)s - %(message)s",
        handlers=[
            logging.FileHandler(log_file, encoding='utf-8', mode='a'),
            logging.StreamHandler()
        ]
    )

def safe_delete(path: Path):
    """安全删除文件或目录"""
    try:
        if path.is_file():
            path.unlink()
            logging.info(f" 已删除文件: {path}")
        elif path.is_dir():
            shutil.rmtree(path)
            logging.info(f" 已删除目录: {path}")
    except Exception as e:
        logging.error(f" 删除 {path} 时出错: {e}")


def extract_and_copy(zip_file_path: Path, target_dir: Path, output_dir: Path) -> bool:
    """
    解压并复制日志文件

    Args:
        zip_file_path: 输入的zip文件路径
        target_dir: 解压目标目录
        output_dir: 输出目录

    Returns:
        bool: 操作是否成功
    """
    try:
        # 解压ZIP文件
        with zipfile.ZipFile(zip_file_path, 'r') as z:
            namelist = z.namelist()
            first_dir = namelist[0].split('/')[0] if namelist else ''
            if(first_dir != 'zlog'):
                z.extractall(target_dir / "zlog")
            else:
                z.extractall(target_dir)
        logging.info(f" 已解压文件至: {target_dir}")

        # 删除压缩包
        safe_delete(zip_file_path)

        # 准备目录结构
        extracted_dir = target_dir / 'zlog'
        if not extracted_dir.exists():
            logging.error(f" 解压目录不存在: {extracted_dir}")
            return False

        # 清空并创建输出目录
        if output_dir.exists():
            safe_delete(output_dir)
        output_dir.mkdir(parents=True, exist_ok=True)

        # 复制有用文件夹
        for folder in ['anr', 'system']:
            src = extracted_dir / folder
            if(not src.exists()):
                continue
            for file in os.listdir(src):
                in_file = src / file
                if(in_file.is_dir() and any(in_file.iterdir())):
                    tar_file = output_dir / folder / file
                    shutil.copytree(in_file,tar_file)
                    logging.info(f" 已复制文件夹: {in_file} -> {tar_file}")

        # 处理ANR日志
        anr_dir = output_dir / 'anr'
        if anr_dir.exists():
            process_anr_folder(anr_dir, target_dir / "tmp_log.txt")

            # 清理临时文件
        safe_delete(extracted_dir)
        return True

    except Exception as e:
        logging.error(f" 处理 {zip_file_path} 时出错: {e}")
        return False

def extract(zip_file_path: Path, target_dir: Path, output_dir: Path) -> bool:
    """
    解压并复制日志文件

    Args:
        zip_file_path: 输入的zip文件路径
        target_dir: 解压目标目录
        output_dir: 输出目录

    Returns:
        bool: 操作是否成功
    """
    try:
        # 解压ZIP文件
        with zipfile.ZipFile(zip_file_path, 'r') as z:
            namelist = z.namelist()
            first_dir = namelist[0].split('/')[0] if namelist else ''
            if(first_dir != 'zlog'):
                z.extractall(target_dir / "zlog")
            else:
                z.extractall(target_dir)
        logging.info(f" 已解压文件至: {target_dir}")

        # 删除压缩包
        safe_delete(zip_file_path)

        # 准备目录结构
        extracted_dir = target_dir / 'zlog'
        if not extracted_dir.exists():
            logging.error(f" 解压目录不存在: {extracted_dir}")
            return False

        # 清空并创建输出目录
        if output_dir.exists():
            safe_delete(output_dir)
        # output_dir.mkdir(parents=True, exist_ok=True)

        shutil.copytree(extracted_dir,output_dir)

        safe_delete(extracted_dir)
        return True

    except Exception as e:
        logging.error(f" 处理 {zip_file_path} 时出错: {e}")
        return False

def process_anr_folder(folder_path: Path, output_file: Path):
    """处理ANR文件夹中的日志"""
    try:
        with output_file.open('w+', encoding='utf-8') as f_out:
            for entry in folder_path.iterdir():
                if entry.is_dir():
                    f_out.write(f"{entry.name} ，慢方法：\n")
                    contents = []
                    # 处理所有blockinfo.txt 文件
                    for block_file in entry.glob('*blockinfo.txt'):
                        try:
                            content = ""
                            with block_file.open('r', encoding='utf-8') as f_in:
                                lines = f_in.readlines()
                                if len(lines) >= 12:
                                    # 写入第5行到倒数第2行
                                    content = "".join(lines[11:])
                            if content in contents:
                                continue
                            contents.append(content)
                            with block_file.open('r', encoding='utf-8') as f_in:
                                lines = f_in.readlines()
                                content = "".join(lines[4:-1])
                            f_out.write(content)
                        except UnicodeDecodeError:
                            logging.warning(f" 文件编码问题: {block_file}")
                        except Exception as e:
                            logging.error(f" 处理 {block_file} 时出错: {e}")
                    f_out.write("\n")
            f_out.seek(0)
            # logging.info(f"提取ANR-blockinfo日志{f_out.read()}")
            logging.info(f" 已提取ANR日志到: {output_file}")
    except Exception as e:
        logging.error(f" 处理ANR文件夹时出错: {e}")


def main():
    setup_logging()
    count = 0
    base_dir = Path("D:/实习生工作")

    print("输入y退出")
    while True:
        try:
            # 获取用户输入
            zipfile_name = input("请输入需要解压的文件：").strip()
            if zipfile_name.lower() == 'y':
                break

            zip_file_path = base_dir / f"{zipfile_name}.gz"
            if not zip_file_path.exists():
                logging.error(f" 文件不存在: {zip_file_path}")
                print(f" 文件不存在: {zip_file_path}")
                continue

            while True:
                sn = input("请输入SN号：").strip()
                if sn.lower() == 'y':
                    break

                if not is_sn_valid(sn):
                    print(f"{sn} 不符合要求，请重新输入SN号")
                    continue

                break

            if sn.lower() == 'y':
                break

            output_dir = base_dir / sn
            logging.info(f" 开始处理 | 文件: {zipfile_name} | SN: {sn}")

            if extract_and_copy(zip_file_path, base_dir, output_dir):
                count += 1
                msg = f"第{count}台设备日志收集成功，SN: {sn}"
                print(msg)
                logging.info(msg)

        except KeyboardInterrupt:
            logging.info(" 用户中断操作")
            break
        except Exception as e:
            logging.error(f" 意外错误: {e}")


if __name__ == "__main__":
    main()